package main

import (
	"fmt"
	"strconv"
	"time"
)

/**
生产者消费者模式
	1、生成者每秒生成一个商品，并通知物流公司取货
	2、物流公司将商品运输都商铺
	3、消费者阻塞等待商铺到货 需要消费10次商品
*/

func main() {

	num := 10
	storageChan := make(chan Product, num) // 存储生成的商品的管道
	shopChan := make(chan Product, num)    // 存储转运给商品的商品的管道
	exitChan := make(chan bool, 1)         // 判断主线程结束的管道

	for i := 1; i < 9; i++ {
		go Producer(storageChan, num)
	}

	go Logistics(storageChan, shopChan)
	go Consummer(shopChan, num, exitChan)
	if <-exitChan {
		return
	}

	fmt.Println(storageChan, shopChan, exitChan)

}

// 商品
type Product struct {
	Name string
}

// 生产者
func Producer(storageChan chan<- Product, count int) {
	for {
		producer := Product{"商品" + strconv.Itoa(count)}
		storageChan <- producer
		count--
		time.Sleep(time.Second)
		fmt.Println("生产了", producer)
		if count < 1 {
			return
		}
	}
}

// 物流公司
func Logistics(storageChan <-chan Product, shopChan chan<- Product) {
	for {
		producer := <-storageChan
		shopChan <- producer
		fmt.Println("运输了", producer)
	}
}

// 消费者
func Consummer(shopChan <-chan Product, count int, exitChan chan<- bool) {
	for {
		producer := <-shopChan
		fmt.Println("消费了", producer)
		count--
		if count < 1 {
			exitChan <- true
			return
		}
	}
}
